home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / ZFILEIO.C < prev    next >
C/C++ Source or Header  |  1992-02-28  |  10KB  |  446 lines

  1. /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* zfileio.c */
  21. /* File I/O operators for Ghostscript */
  22. #include "ghost.h"
  23. #include "gp.h"
  24. #include "errors.h"
  25. #include "oper.h"
  26. #include "stream.h"
  27. #include "estack.h"
  28. #include "file.h"
  29. #include "store.h"
  30. #include "gsmatrix.h"            /* for gxdevice.h */
  31. #include "gxdevice.h"
  32. #include "gxdevmem.h"
  33.  
  34. /* Forward references */
  35. int zreadline_from(P4(byte *, uint, uint *, stream *));
  36. ref *zget_current_file(P0());
  37. private int write_string(P2(os_ptr, stream *));
  38.  
  39. /* ------ Operators ------ */
  40.  
  41. /* read */
  42. int
  43. zread(register os_ptr op)
  44. {    stream *s;
  45.     int ch;
  46.     check_read_file(s, op);
  47.     check_read(*op);
  48.     ch = sgetc(s);
  49.     if ( ch == EOFC )
  50.         make_bool(op, 0);
  51.     else
  52.        {    make_int(op, ch);
  53.         push(1);
  54.         make_bool(op, 1);
  55.        }
  56.     return 0;
  57. }
  58.  
  59. /* write */
  60. int
  61. zwrite(register os_ptr op)
  62. {    stream *s;
  63.     ulong ch;
  64.     check_write_file(s, op - 1);
  65.     check_write(op[-1]);
  66.     check_type(*op, t_integer);
  67.     ch = op->value.intval;
  68.     if ( ch > 0xff ) return e_rangecheck;
  69.     sputc(s, (byte)ch);
  70.     pop(2);
  71.     return 0;
  72. }
  73.  
  74. /* readhexstring */
  75. int
  76. zreadhexstring(register os_ptr op)
  77. {    stream *s;
  78.     os_ptr op1 = op - 1;
  79.     int odd = -1;
  80.     int code;
  81.     uint nread;
  82.     check_read_file(s, op1);
  83.     check_read(*op1);
  84.     check_type(*op, t_string);
  85.     check_write(*op);
  86.     code = sreadhex(s, op->value.bytes, r_size(op), &nread, &odd, 1);
  87.     switch ( code )
  88.        {
  89.     case EOFC:
  90.         /* Reached end-of-file before filling the string. */
  91.         /* Return an appropriate substring. */
  92.         r_set_size(op, nread);
  93.         code = 1;
  94.         break;
  95.     case 0:
  96.         /* Filled the string. */
  97.         break;
  98.     default:            /* Error */
  99.         return e_ioerror;
  100.        }
  101.     *op1 = *op;
  102.     make_bool(op, 1 - code);
  103.     return 0;
  104. }
  105.  
  106. /* writehexstring */
  107. int
  108. zwritehexstring(register os_ptr op)
  109. {    register stream *s;
  110.     register byte ch;
  111.     register byte *p;
  112.     register char _ds *hex_digits = "0123456789abcdef";
  113.     register uint len;
  114.     check_write_file(s, op - 1);
  115.     check_write(op[-1]);
  116.     check_read_type(*op, t_string);
  117.     p = op->value.bytes;
  118.     len = r_size(op);
  119.     while ( len-- )
  120.        {    ch = *p++;
  121.         sputc(s, hex_digits[ch >> 4]);
  122.         sputc(s, hex_digits[ch & 0xf]);
  123.        }
  124.     pop(2);
  125.     return 0;
  126. }
  127.  
  128. /* readstring */
  129. int
  130. zreadstring(register os_ptr op)
  131. {    stream *s;
  132.     uint len, rlen;
  133.     check_read_file(s, op - 1);
  134.     check_read(op[-1]);
  135.     check_write_type(*op, t_string);
  136.     len = r_size(op);
  137.     rlen = sgets(s, op->value.bytes, len);
  138.     r_set_size(op, rlen);
  139.     op[-1] = *op;
  140.     make_bool(op, (rlen == len ? 1 : 0));
  141.     return 0;
  142. }
  143.  
  144. /* writestring */
  145. int
  146. zwritestring(register os_ptr op)
  147. {    stream *s;
  148.     int code;
  149.     check_write_file(s, op - 1);
  150.     check_write(op[-1]);
  151.     code = write_string(op, s);
  152.     if ( code >= 0 ) pop(2);
  153.     return code;
  154. }
  155.  
  156. /* readline */
  157. int
  158. zreadline(register os_ptr op)
  159. {    stream *s;
  160.     uint count;
  161.     int code;
  162.     check_read_file(s, op - 1);
  163.     check_read(op[-1]);
  164.     check_write_type(*op, t_string);
  165.     code = zreadline_from(op->value.bytes, r_size(op), &count, s);
  166.     if ( code < 0 ) return code;
  167.     r_set_size(op, count);
  168.     op[-1] = *op;
  169.     make_bool(op, code);
  170.     return 0;
  171. }
  172.  
  173. /* Read a line from stdin.  This is called from gs.c. */
  174. int
  175. zreadline_stdin(byte *ptr, uint size, uint *pcount)
  176. {    return zreadline_from(ptr, size, pcount, &std_files[0]);
  177. }
  178.  
  179. /* Internal readline routine. */
  180. /* Returns 1 if OK, 0 if end of file, or an error code. */
  181. int
  182. zreadline_from(byte *ptr, uint size, uint *pcount, stream *s)
  183. {    uint count = 0;
  184.     int ch;
  185.     for ( ; ; count++ )
  186.        {    switch ( ch = sgetc(s) )
  187.            {
  188.         case '\r':
  189.             ch = sgetc(s);
  190.             if ( ch != '\n' && ch >= 0 ) sputback(s);
  191.             /* falls through */
  192.         case '\n':
  193.             *pcount = count;
  194.             return 1;
  195.         case EOFC:
  196.             *pcount = count;
  197.             return 0;
  198.            }
  199.         if ( count >= size )    /* filled the string */
  200.            {    sputback(s);
  201.             return e_rangecheck;
  202.            }
  203.         *ptr++ = ch;
  204.        }
  205.     return 0;
  206. }
  207.  
  208. /* token - this is called from zstring.c */
  209. int
  210. ztoken_file(register os_ptr op)
  211. {    stream *s;
  212.     ref token;
  213.     int code;
  214.     check_read_file(s, op);
  215.     check_read(*op);
  216.     switch ( code = scan_token(s, 0, &token) )
  217.        {
  218.     case 0:                /* read a token */
  219.         *op = token;
  220.         push(1);
  221.         make_bool(op, 1);
  222.         return 0;
  223.     case 1:                /* no tokens */
  224.         make_bool(op, 0);
  225.         return 0;
  226.     default:            /* error */
  227.         return code;
  228.        }
  229. }
  230.  
  231. /* bytesavailable */
  232. int
  233. zbytesavailable(register os_ptr op)
  234. {    stream *s;
  235.     long avail;
  236.     check_read_file(s, op);
  237.     if ( savailable(s, &avail) < 0 ) return e_ioerror;
  238.     make_int(op, avail);
  239.     return 0;
  240. }
  241.  
  242. /* flush */
  243. int
  244. zflush(register os_ptr op)
  245. {    sflush(&std_files[1]);
  246.     return 0;
  247. }
  248.  
  249. /* flushfile */
  250. int
  251. zflushfile(register os_ptr op)
  252. {    stream *s;
  253.     check_file(s, op);
  254.     sflush(s);
  255.     if ( !s_is_writing(s) )
  256.         fseek(s->file, 0L, 2);    /* set to end */
  257.     pop(1);
  258.     return 0;
  259. }
  260.  
  261. /* resetfile */
  262. int
  263. zresetfile(register os_ptr op)
  264. {    NYI("resetfile");
  265.     pop(1);
  266.     return 0;
  267. }
  268.  
  269. /* status */
  270. int
  271. zstatus(register os_ptr op)
  272. {    switch ( r_type(op) )
  273.        {
  274.     case t_file:
  275.         make_bool(op, (fptr(op)->bsize != 0 ? 1 : 0));
  276.         return 0;
  277.     case t_string:
  278.        {    char *fname = ref_to_string(op, "status");
  279.         file_status fstat;
  280.         if ( fname == 0 ) return e_VMerror;
  281.         if ( gp_file_status(fname, &fstat) )
  282.            {    push(4);
  283.             make_int(op - 4, fstat.size_pages);
  284.             make_int(op - 3, fstat.size_bytes);
  285.             make_int(op - 2, fstat.time_referenced);
  286.             make_int(op - 1, fstat.time_created);
  287.             make_bool(op, 1);
  288.            }
  289.         else
  290.             make_bool(op, 0);
  291.         alloc_free(fname, r_size(op) + 1, 1, "status");
  292.        }    return 0;
  293.     default:
  294.         return e_typecheck;
  295.        }
  296. }
  297.  
  298. /* currentfile */
  299. int
  300. zcurrentfile(register os_ptr op)
  301. {    ref *fp;
  302.     push(1);
  303.     if ( (fp = zget_current_file()) == 0 )
  304.        {    /* Return an invalid file object. */
  305.         /* This doesn't make a lot of sense to me, */
  306.         /* but it's what the PostScript manual specifies. */
  307.         make_file(op, 0, &invalid_file_entry);
  308.        }
  309.     else
  310.         *op = *fp;
  311.     /* Make sure the returned value is literal. */
  312.     r_clear_attrs(op, a_executable);
  313.     return 0;
  314. }
  315.  
  316. /* print */
  317. int
  318. zprint(register os_ptr op)
  319. {    int code = write_string(op, &std_files[1]);
  320.     if ( code >= 0 ) pop(1);
  321.     return code;
  322. }
  323.  
  324. /* echo */
  325. int
  326. zecho(register os_ptr op)
  327. {    check_type(*op, t_boolean);
  328.     /****** NOT IMPLEMENTED YET ******/
  329.     pop(1);
  330.     return 0;
  331. }
  332.  
  333. /* ------ Level 2 extensions ------ */
  334.  
  335. /* fileposition */
  336. int
  337. zfileposition(register os_ptr op)
  338. {    stream *s;
  339.     check_file(s, op);
  340.     if ( !sseekable(s) ) return e_ioerror;
  341.     make_int(op, stell(s));
  342.     return 0;
  343. }
  344.  
  345. /* setfileposition */
  346. int
  347. zsetfileposition(register os_ptr op)
  348. {    stream *s;
  349.     check_file(s, op - 1);
  350.     check_type(*op, t_integer);
  351.     if ( sseek(s, op->value.intval) < 0 ) return e_ioerror;
  352.     pop(2);
  353.     return 0;
  354. }
  355.  
  356. /* ------ Ghostscript extensions ------ */
  357.  
  358. /* unread */
  359. int
  360. zunread(register os_ptr op)
  361. {    stream *s;
  362.     ulong ch;
  363.     check_read_file(s, op - 1);
  364.     check_type(*op, t_integer);
  365.     ch = op->value.intval;
  366.     if ( ch > 0xff ) return e_rangecheck;
  367.     if ( sungetc(s, (byte)ch) < 0 ) return e_ioerror;
  368.     pop(2);
  369.     return 0;
  370. }
  371.  
  372. /* writeppmfile */
  373. int
  374. zwriteppmfile(register os_ptr op)
  375. {    stream *s;
  376.     int code;
  377.     check_write_file(s, op - 1);
  378.     check_write(op[-1]);
  379.     check_type(*op, t_device);
  380.     if ( !gs_device_is_memory(op->value.pdevice) ) return e_typecheck;
  381.     sflush(s);
  382.     code = gs_writeppmfile((gx_device_memory *)(op->value.pdevice), s->file);
  383.     if ( code >= 0 ) pop(2);
  384.     return code;
  385. }
  386.  
  387. /* ------ Initialization procedure ------ */
  388.  
  389. op_def zfileio_op_defs[] = {
  390.     {"1bytesavailable", zbytesavailable},
  391.     {"0currentfile", zcurrentfile},
  392.     {"1echo", zecho},
  393.     {"1fileposition", zfileposition},
  394.     {"0flush", zflush},
  395.     {"1flushfile", zflushfile},
  396.     {"1print", zprint},
  397.     {"1read", zread},
  398.     {"2readhexstring", zreadhexstring},
  399.     {"2readline", zreadline},
  400.     {"2readstring", zreadstring},
  401.     {"1resetfile", zresetfile},
  402.     {"2setfileposition", zsetfileposition},
  403.     {"2unread", zunread},
  404.     {"1status", zstatus},
  405.     {"2write", zwrite},
  406.     {"2writehexstring", zwritehexstring},
  407.     {"2writeppmfile", zwriteppmfile},
  408.     {"2writestring", zwritestring},
  409.     op_def_end(0)
  410. };
  411.  
  412. /* ------ Non-operator routines ------ */
  413.  
  414. /* Check a file for reading. */
  415. /* The interpreter calls this to check an executable file. */
  416. int
  417. file_check_read(ref *op, stream **ps)
  418. {    if ( !s_is_reading(*ps = fptr(op)) ) return e_invalidaccess;
  419.     return 0;
  420. }
  421.  
  422. /* Get the current file from which the interpreter is reading. */
  423. ref *
  424. zget_current_file()
  425. {    es_ptr ep = esp;
  426.     while ( ep >= esbot )
  427.     {    if ( r_has_type(ep, t_file) && r_has_attr(ep, a_executable) )
  428.             return (ref *)ep;
  429.         ep--;
  430.     }
  431.     return (ref *)0;
  432. }
  433.  
  434. /* ------ Internal routines ------ */
  435.  
  436. /* Write a string on a file.  The file has been checked for validity, */
  437. /* but not the string. */
  438. private int
  439. write_string(os_ptr op, stream *s)
  440. {    uint len;
  441.     check_read_type(*op, t_string);
  442.     len = r_size(op);
  443.     if ( sputs(s, op->value.bytes, len) != len ) return e_ioerror;
  444.     return 0;
  445. }
  446.